<template>
  <div class="fire-realtime-detection">
    <div class="page-header">
      <h1>🔥 火灾实时检测系统</h1>
      <p>基于AI的智能火灾检测与预警系统</p>
    </div>

    <!-- 系统状态面板 -->
    <div class="status-panel">
      <div class="status-card">
        <div class="status-item">
          <span class="status-label">Ollama连接:</span>
          <span :class="['status-value', systemStatus.ollama_connected ? 'connected' : 'disconnected']">
            {{ systemStatus.ollama_connected ? '✅ 已连接' : '❌ 未连接' }}
          </span>
        </div>
        <div class="status-item">
          <span class="status-label">检测队列:</span>
          <span class="status-value">{{ systemStatus.queue_size }} 个任务</span>
        </div>
        <div class="status-item">
          <span class="status-label">处理状态:</span>
          <span :class="['status-value', systemStatus.is_processing ? 'processing' : 'idle']">
            {{ systemStatus.is_processing ? '🔄 处理中' : '✅ 空闲' }}
          </span>
        </div>
        <div class="status-item">
          <span class="status-label">报警次数:</span>
          <span class="status-value alarm-count">{{ systemStatus.alarm_count }}</span>
        </div>
      </div>
    </div>

    <!-- 主要功能区域 -->
    <div class="main-content">
      <!-- 视频检测区域 -->
      <div class="video-section">
        <div class="section-header">
          <h2>📷 实时视频检测</h2>
        </div>
        <div class="control-buttons">
            <a-button 
              type="primary" 
              :loading="isStartingCamera"
              @click="startCamera"
              :disabled="isCameraActive"
            >
              <template #icon><icon-camera /></template>
              连接视频流
            </a-button>
            <a-button 
              type="default" 
              @click="stopCamera"
              :disabled="!isCameraActive"
            >
              <template #icon><icon-close /></template>
              断开视频流
            </a-button>
            <a-button 
              type="primary" 
              :loading="isDetecting"
              @click="startDetection"
              :disabled="!isCameraActive || isDetecting"
            >
              <template #icon><icon-play-arrow /></template>
              开始检测
            </a-button>
            <a-button 
              type="default" 
              @click="stopDetection"
              :disabled="!isDetecting"
            >
              <template #icon><icon-pause /></template>
              停止检测
            </a-button>
        </div>
        
        <div class="video-container">
          <video 
            ref="videoElement"
            class="video-stream"
            autoplay
            muted
            playsinline
          ></video>
          <div v-if="!isCameraActive" class="video-placeholder">
            <icon-camera size="48" />
            <p>视频流未连接</p>
            <p class="placeholder-hint">请先启动客户端程序，然后点击"连接视频流"</p>
          </div>
        </div>
      </div>

    </div>

    <!-- 检测结果区域 -->
    <div class="results-section">
      <div class="section-header">
        <h2>📊 检测结果</h2>
        <div class="result-controls">
          <a-button @click="clearResults">清空结果</a-button>
          <a-button @click="testAlarm">测试警报</a-button>
          <a-button @click="stopAlarm">停止警报</a-button>
        </div>
      </div>
      
      <!-- 当前检测结果 -->
      <div v-if="currentResult" class="current-result">
        <div :class="['result-card', currentResult.has_fire ? 'fire-detected' : 'safe']">
          <div class="result-header">
            <h3>{{ currentResult.has_fire ? '🔥 检测到火灾' : '✅ 安全' }}</h3>
            <span class="confidence">{{ (currentResult.confidence * 100).toFixed(1) }}%</span>
          </div>
          <div class="result-details">
            <p><strong>AI分析:</strong> {{ currentResult.raw_response }}</p>
            <p><strong>检测时间:</strong> {{ currentResult.timestamp }}</p>
            <p v-if="currentResult.task_id"><strong>任务ID:</strong> {{ currentResult.task_id }}</p>
          </div>
        </div>
      </div>

      <!-- 检测历史 -->
      <div class="detection-history">
        <h3>检测历史</h3>
        <div class="history-list">
          <div 
            v-for="(result, index) in detectionHistory" 
            :key="index"
            :class="['history-item', result.has_fire ? 'fire-detected' : 'safe']"
          >
            <div class="history-icon">
              {{ result.has_fire ? '🔥' : '✅' }}
            </div>
            <div class="history-content">
              <div class="history-time">{{ result.timestamp }}</div>
              <div class="history-confidence">置信度: {{ (result.confidence * 100).toFixed(1) }}%</div>
              <div class="history-response">{{ result.raw_response }}</div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 警报通知 -->
    <a-modal 
      v-model:visible="showAlarmModal" 
      title="🚨 火灾警报" 
      :footer="null"
      :closable="false"
      :mask-closable="false"
    >
      <div class="alarm-content">
        <div class="alarm-icon">🔥</div>
        <h3>检测到火灾迹象！</h3>
        <p><strong>时间:</strong> {{ alarmData.timestamp }}</p>
        <p><strong>置信度:</strong> {{ (alarmData.confidence * 100).toFixed(1) }}%</p>
        <p><strong>AI分析:</strong> {{ alarmData.raw_response }}</p>
        <p><strong>报警次数:</strong> {{ alarmData.alarm_count }}</p>
        <div class="alarm-actions">
          <a-button type="primary" danger @click="acknowledgeAlarm">确认警报</a-button>
          <a-button @click="stopAlarm">停止警报</a-button>
        </div>
      </div>
    </a-modal>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, onUnmounted } from 'vue'
import { Message } from '@arco-design/web-vue'
import { 
  IconCamera, 
  IconClose, 
  IconPlayArrow, 
  IconPause
} from '@arco-design/web-vue/es/icon'
import { io } from 'socket.io-client'

// 响应式数据
const videoElement = ref(null)
const stream = ref(null)
const detectionInterval = ref(null)
const taskId = ref(0)

// 视频流处理相关
const videoCanvas = ref(null)
const videoCtx = ref(null)
const lastFrameTime = ref(0)
const frameRate = 30 // 目标帧率
const frameInterval = 1000 / frameRate // 帧间隔(ms)

// 状态管理
const isCameraActive = ref(false)
const isStartingCamera = ref(false)
const isDetecting = ref(false)
const showAlarmModal = ref(false)

// 系统状态
const systemStatus = reactive({
  ollama_connected: false,
  queue_size: 0,
  is_processing: false,
  alarm_count: 0
})

// 检测结果
const currentResult = ref(null)
const detectionHistory = ref([])
const alarmData = ref({})

// WebSocket连接
let socket = null
const API_BASE_URL = 'http://localhost:8080'  // 火灾检测API服务地址

// 初始化视频canvas
const initVideoCanvas = () => {
  if (!videoCanvas.value) {
    videoCanvas.value = document.createElement('canvas')
    videoCanvas.value.width = 1280
    videoCanvas.value.height = 720
    videoCtx.value = videoCanvas.value.getContext('2d')
    
    // 创建稳定的视频流
    stream.value = videoCanvas.value.captureStream(frameRate)
    if (videoElement.value) {
      videoElement.value.srcObject = stream.value
    }
  }
}

// 更新视频帧
const updateVideoFrame = (frameData) => {
  const currentTime = Date.now()
  
  // 帧率控制
  if (currentTime - lastFrameTime.value < frameInterval) {
    return
  }
  
  lastFrameTime.value = currentTime
  
  if (videoCtx.value && frameData) {
    const img = new Image()
    img.onload = () => {
      // 清除canvas
      videoCtx.value.clearRect(0, 0, videoCanvas.value.width, videoCanvas.value.height)
      
      // 计算缩放比例，保持宽高比
      const scale = Math.min(
        videoCanvas.value.width / img.width,
        videoCanvas.value.height / img.height
      )
      
      const scaledWidth = img.width * scale
      const scaledHeight = img.height * scale
      const x = (videoCanvas.value.width - scaledWidth) / 2
      const y = (videoCanvas.value.height - scaledHeight) / 2
      
      // 绘制图像
      videoCtx.value.drawImage(img, x, y, scaledWidth, scaledHeight)
    }
    img.src = `data:image/jpeg;base64,${frameData}`
  }
}

// 启动摄像头（连接到客户端视频流）
const startCamera = async () => {
  try {
    isStartingCamera.value = true
    
    // 连接到WebSocket服务器
    if (!socket) {
      socket = io(API_BASE_URL, {
        transports: ['websocket', 'polling']
      })
      
      // 监听连接事件
      socket.on('connect', () => {
        console.log('已连接到火灾检测服务')
        Message.success('已连接到视频流服务')
        
        // 初始化视频canvas
        initVideoCanvas()
        isCameraActive.value = true
      })
      
      // 监听视频帧数据
      socket.on('video_frame', (data) => {
        if (data.frame) {
          updateVideoFrame(data.frame)
        }
      })
      
      // 监听检测结果
      socket.on('detection_result', (data) => {
        displayResult(data, ++taskId.value)
        
        // 如果检测到火灾，触发警报
        if (data.has_fire && data.confidence >= 0.7) {
          triggerFireAlarm(data)
        }
      })
      
      // 监听检测错误
      socket.on('detection_error', (data) => {
        Message.error('检测错误: ' + data.error)
      })
      
      // 监听连接断开
      socket.on('disconnect', () => {
        console.log('与服务器断开连接')
        Message.warning('与服务器断开连接')
        isCameraActive.value = false
      })
      
      // 请求视频流状态
      socket.emit('request_video_stream')
    } else {
      Message.info('视频流已连接')
    }
    
  } catch (error) {
    console.error('启动视频流失败:', error)
    Message.error('无法连接到视频流服务: ' + error.message)
  } finally {
    isStartingCamera.value = false
  }
}

// 停止摄像头
const stopCamera = () => {
  if (socket) {
    socket.disconnect()
    socket = null
  }
  
  if (stream.value) {
    stream.value.getTracks().forEach(track => track.stop())
    stream.value = null
  }
  
  if (videoElement.value) {
    videoElement.value.srcObject = null
  }
  
  // 清理视频canvas
  if (videoCanvas.value) {
    videoCanvas.value = null
    videoCtx.value = null
  }
  
  isCameraActive.value = false
  stopDetection()
  Message.info('视频流已停止')
}

// 开始检测
const startDetection = () => {
  if (!isCameraActive.value) {
    Message.warning('请先启动视频流')
    return
  }
  
  if (socket) {
    socket.emit('start_detection')
    isDetecting.value = true
    Message.success('开始实时检测')
  } else {
    Message.error('未连接到服务器')
  }
}

// 停止检测
const stopDetection = () => {
  if (socket) {
    socket.emit('stop_detection')
  }
  
  if (detectionInterval.value) {
    clearInterval(detectionInterval.value)
    detectionInterval.value = null
  }
  
  isDetecting.value = false
  Message.info('检测已停止')
}

// 检测现在由服务器端处理，通过WebSocket接收结果

// 显示检测结果
const displayResult = (result, id) => {
  currentResult.value = { ...result, task_id: id }
  addToHistory(result, id)
}

// 添加到历史记录
const addToHistory = (result, id) => {
  const historyItem = {
    ...result,
    task_id: id,
    timestamp: result.timestamp || new Date().toLocaleString()
  }
  
  detectionHistory.value.unshift(historyItem)
  
  // 限制历史记录数量
  if (detectionHistory.value.length > 20) {
    detectionHistory.value = detectionHistory.value.slice(0, 20)
  }
}

// 清空结果
const clearResults = () => {
  currentResult.value = null
  detectionHistory.value = []
  Message.success('结果已清空')
}

// 测试警报
const testAlarm = () => {
  // 模拟测试警报
  const testData = {
    has_fire: true,
    confidence: 0.95,
    raw_response: '测试：检测到火灾迹象',
    timestamp: new Date().toLocaleString()
  }
  triggerFireAlarm(testData)
  Message.success('警报测试已触发')
}

// 停止警报
const stopAlarm = () => {
  showAlarmModal.value = false
  Message.success('警报已停止')
}

// 触发火灾警报
const triggerFireAlarm = (detectionResult) => {
  alarmData.value = {
    timestamp: detectionResult.timestamp,
    confidence: detectionResult.confidence,
    raw_response: detectionResult.raw_response,
    alarm_count: systemStatus.alarm_count + 1
  }
  showAlarmModal.value = true
  
  // 播放警报音效
  if ('AudioContext' in window) {
    try {
      const audioContext = new AudioContext()
      const oscillator = audioContext.createOscillator()
      const gainNode = audioContext.createGain()
      
      oscillator.connect(gainNode)
      gainNode.connect(audioContext.destination)
      
      oscillator.frequency.setValueAtTime(800, audioContext.currentTime)
      gainNode.gain.setValueAtTime(0.3, audioContext.currentTime)
      
      oscillator.start()
      oscillator.stop(audioContext.currentTime + 0.5)
    } catch (error) {
      console.error('播放警报音效失败:', error)
    }
  }
}

// 确认警报
const acknowledgeAlarm = () => {
  showAlarmModal.value = false
  stopAlarm()
}

// 检查系统状态
const checkStatus = () => {
  fetch(`${API_BASE_URL}/health`)
    .then(response => response.json())
    .then(data => {
      systemStatus.ollama_connected = data.ollama_connected || false
      systemStatus.queue_size = data.queue_size || 0
      systemStatus.is_processing = data.is_processing || false
      systemStatus.alarm_count = data.alarm_count || 0
    })
    .catch(error => {
      console.error('状态检查失败:', error)
      // 如果连接失败，显示默认状态
      systemStatus.ollama_connected = false
      systemStatus.queue_size = 0
      systemStatus.is_processing = false
      systemStatus.alarm_count = 0
    })
}

// 初始化检测系统
const initDetectionSystem = () => {
  try {
    console.log('火灾检测系统初始化完成')
    console.log('使用同步API进行实时检测')
  } catch (error) {
    console.error('检测系统初始化失败:', error)
  }
}

// 组件挂载
onMounted(() => {
  checkStatus()
  initDetectionSystem()
  
  // 定期检查状态
  const statusInterval = setInterval(checkStatus, 2000)
  
  // 清理定时器和连接
  onUnmounted(() => {
    clearInterval(statusInterval)
    stopCamera()
    if (socket) {
      socket.disconnect()
    }
  })
})
</script>

<style scoped>
.fire-realtime-detection {
  padding: 20px;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  min-height: 100vh;
  color: white;
}

.page-header {
  text-align: center;
  margin-bottom: 30px;
}

.page-header h1 {
  font-size: 2.5rem;
  margin-bottom: 10px;
  text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
}

.page-header p {
  font-size: 1.2rem;
  opacity: 0.9;
}

.status-panel {
  margin-bottom: 30px;
}

.status-card {
  background: rgba(255, 255, 255, 0.1);
  backdrop-filter: blur(10px);
  border-radius: 15px;
  padding: 20px;
  display: flex;
  gap: 30px;
  flex-wrap: wrap;
}

.status-item {
  display: flex;
  align-items: center;
  gap: 10px;
}

.status-label {
  font-weight: 600;
  opacity: 0.9;
}

.status-value {
  font-weight: 700;
  padding: 5px 10px;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.2);
}

.status-value.connected {
  background: rgba(76, 175, 80, 0.3);
  color: #4caf50;
}

.status-value.disconnected {
  background: rgba(244, 67, 54, 0.3);
  color: #f44336;
}

.status-value.processing {
  background: rgba(255, 193, 7, 0.3);
  color: #ffc107;
}

.status-value.idle {
  background: rgba(76, 175, 80, 0.3);
  color: #4caf50;
}

.alarm-count {
  background: rgba(244, 67, 54, 0.3);
  color: #f44336;
}

.main-content {
  display: flex;
  flex-direction: column;
  gap: 30px;
  margin-bottom: 30px;
}

.section-header {
  display: flex;
  justify-content: center;
  align-items: center;
  margin-bottom: 20px;
}

.section-header h2 {
  font-size: 1.5rem;
  margin: 0;
}

.control-buttons {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  justify-content: center;
  margin-bottom: 20px;
}

.video-container {
  position: relative;
  background: rgba(0, 0, 0, 0.3);
  border-radius: 15px;
  overflow: hidden;
  aspect-ratio: 16/9;
  max-width: 800px;
  max-height: 450px;
  margin: 0 auto;
}

.video-stream {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.video-placeholder {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: rgba(255, 255, 255, 0.6);
  text-align: center;
}

.placeholder-hint {
  font-size: 0.9rem;
  opacity: 0.7;
  margin-top: 10px;
  max-width: 300px;
}


.results-section {
  background: rgba(255, 255, 255, 0.1);
  backdrop-filter: blur(10px);
  border-radius: 15px;
  padding: 20px;
}

.result-controls {
  display: flex;
  gap: 10px;
}

.current-result {
  margin-bottom: 30px;
}

.result-card {
  padding: 20px;
  border-radius: 12px;
  border: 2px solid;
}

.result-card.fire-detected {
  background: rgba(244, 67, 54, 0.2);
  border-color: #f44336;
}

.result-card.safe {
  background: rgba(76, 175, 80, 0.2);
  border-color: #4caf50;
}

.result-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
}

.result-header h3 {
  margin: 0;
  font-size: 1.3rem;
}

.confidence {
  font-size: 1.2rem;
  font-weight: 700;
  padding: 5px 15px;
  border-radius: 20px;
  background: rgba(255, 255, 255, 0.2);
}

.result-details p {
  margin: 8px 0;
  opacity: 0.9;
}

.detection-history h3 {
  margin-bottom: 15px;
  font-size: 1.2rem;
}

.history-list {
  max-height: 400px;
  overflow-y: auto;
}

.history-item {
  display: flex;
  align-items: center;
  gap: 15px;
  padding: 12px;
  margin-bottom: 10px;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.05);
  border-left: 4px solid;
}

.history-item.fire-detected {
  border-left-color: #f44336;
}

.history-item.safe {
  border-left-color: #4caf50;
}

.history-icon {
  font-size: 1.5rem;
}

.history-content {
  flex: 1;
}

.history-time {
  font-size: 0.9rem;
  opacity: 0.8;
  margin-bottom: 4px;
}

.history-confidence {
  font-weight: 600;
  margin-bottom: 4px;
}

.history-response {
  font-size: 0.9rem;
  opacity: 0.9;
}

.alarm-content {
  text-align: center;
  padding: 20px;
}

.alarm-icon {
  font-size: 4rem;
  margin-bottom: 20px;
}

.alarm-content h3 {
  color: #f44336;
  margin-bottom: 20px;
}

.alarm-content p {
  margin: 10px 0;
  text-align: left;
}

.alarm-actions {
  margin-top: 30px;
  display: flex;
  gap: 15px;
  justify-content: center;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .status-card {
    flex-direction: column;
    gap: 15px;
  }
  
  .control-buttons {
    flex-direction: column;
  }
  
  .section-header {
    flex-direction: column;
    gap: 15px;
    align-items: stretch;
  }
  
  .video-container {
    max-width: 100%;
    max-height: 300px;
  }
}
</style>
